<!-- <!DOCTYPE html>
<meta charset="utf-8">
<head>
	<title>Tree layout</title>
</head>

<style>
	body {
		font-family: "Helvetica Neue", Helvetica, sans-serif;
		font-size: 9px;
	}

	.links path {
		fill: none;
		stroke: #ccc;
	}
</style>

<body>

	<svg width="800" height="920">
		<g class="wrapper" transform="translate(20, 20)">
			<g class="links"></g>
			<g class="nodes"></g>
		</g>
	</svg>

	<script src="//d3js.org/d3.v4.min.js"></script>
	<script>


var treeLayout = d3.tree()
	.size([900, 600]);

function link(d) {
	return "M" + d.y + "," + d.x
    + "C" + (d.y + d.parent.y) / 2 + "," + d.x
    + " " + (d.y + d.parent.y) / 2 + "," + d.parent.x
    + " " + d.parent.y + "," + d.parent.x;
}

function make(root) {
	var nodes = d3.select('.nodes')
		.selectAll('g.node')
		.data(root.descendants());

	var enteringNodes = nodes.enter()
		.append('g')
		.classed('node', true)
		.attr('transform', function(d) {
			return 'translate(' + d.y + ',' + d.x + ')';
		});

	enteringNodes
		.append('circle')
		.attr('r', 2);

	enteringNodes
		.append('text')
		.attr('x', 5)
		.attr('y', 4)
		.text(function(d) {
			switch(d.depth) {
			case 1:
			case 2:
				return d.data.key;
			case 3:
				return d.data.name;
			}

			return '';
		});

	var links = d3.select('.links')
		.selectAll('path')
		.data(root.descendants().slice(1));

	links.enter()
		.append('path')
		.attr('d', link);
}


function ready(err, data) {
  // root = json;
// root.fixed = true;
// root.x = w / 2;
// root.y = h / 4;

	var nest = d3.nest()
	  .key(function(d) { return d.url; })
	  // .key(function(d) { return d['Lead Studio']; })
	  .entries(data);
console.log(nest)
	nest = {
		key: 'root',
		values: nest
	};

	var root = d3.hierarchy(nest, function(d) {
		return d.values;
	});

	treeLayout(root);
	make(root);
}

// d3.csv('films.csv', ready);

d3.json("./tmp/crawl.json", ready);

	</script>
</body>
</html> -->


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>SPA pages</title>
    <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>

    <style>
      @import url(http://fonts.googleapis.com/css?family=Source+Code+Pro:400,600);
      body {font-family: "Source Code Pro", Consolas, monaco, monospace; line-height: 160%; font-size: 16px;  margin: 0; }
      path.link {
        fill: none;
        stroke-width: 2px;
      }
      .node:not(:hover) .nodetext {
        display: none;
      }
      h1 { font-size: 36px; margin: 10px 0; text-transform: uppercase; font-weight: normal;}
      h2, h3 { font-size: 18px; margin: 5px 0 ; font-weight: normal;}
      header {padding: 20px; position: absolute; top: 0; left: 0;}
      a:link { color: #EE3124; text-decoration: none;}
      a:visited { color: #EE3124; }
      a:hover { color: #A4CD39; text-decoration: underline;}
      a:active { color: #EE3124; }
    </style>
</head>


<body>
    <header>
      <h1>Site pages</h1>
      <h2>Click to view their identity</h2>
      <h3>And link to their web page!</h3>
    </header>
    <section id="vis"></section>
<script>

// some colour variables
  var tcBlack = "#130C0E";

// rest of vars
var w = 960,
    h = 800,
    maxNodeSize = 100,
    x_browser = 20,
    y_browser = 25,
    root;

var vis;
var force = d3.layout.force();

vis = d3.select("#vis").append("svg").attr("width", w).attr("height", h);

d3.json("./output/https___santatracker.google.com_/crawl.json", function(json) {
  root = json;
  root.fixed = true;
  root.x = w / 2;
  root.y = h / 2;

  // Build the path
  var defs = vis.insert("svg:defs").data(["end"]);
  defs.enter().append("svg:path").attr("d", "M0,-5L10,0L0,5");

  update();
});

/**
 *
 */
function update() {
  var nodes = flatten(root),
      links = d3.layout.tree().links(nodes);

  // Restart the force layout.
  force.nodes(nodes)
        .links(links)
        .gravity(0.05)
    .charge(-1500)
    .linkDistance(150)
    .friction(0.5)
    .linkStrength(function(l, i) {return 1; })
    .size([w, h])
    .on("tick", tick)
        .start();

   var path = vis.selectAll("path.link")
      .data(links, function(d) { return d.target.id; });

    path.enter().insert("svg:path")
      .attr("class", "link")
      // .attr("marker-end", "url(#end)")
      .style("stroke", "#eee");


  // Exit any old paths.
  path.exit().remove();



  // Update the nodes…
  var node = vis.selectAll("g.node")
      .data(nodes, function(d) { return d.id; });


  // Enter any new nodes.
  var nodeEnter = node.enter().append("svg:g")
      .attr("class", "node")
      .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
      .on("click", click)
      .call(force.drag);

  // Append a circle
  nodeEnter.append("svg:circle")
      .attr("r", function(d) { return Math.sqrt(d.size) / 10 || 4.5; })
      .style("fill", "#eee");


  // Append images
  var images = nodeEnter.append("svg:image")
        .attr("xlink:href",  function(d) { return d.img;})
        .attr("x", function(d) { return -25;})
        .attr("y", function(d) { return -25;})
        .attr("height", 50)
        .attr("width", 50);

  // make the image grow a little on mouse over and add the text details on click
  var setEvents = images
          // Append hero text
          .on( 'click', function (d) {
              // d3.select("h1").html(d.url);
              d3.select("h2").html(d.name);
              d3.select("h3").html (`Take me to <a href="${d.link}" target="_blank">${d.link || d.name} ⇢</a>`);
           })

          .on( 'mouseenter', function() {
            // select element in current context
            this.parentNode.parentNode.appendChild(this.parentNode);
            d3.select( this )
              .transition()
              .attr("x", function(d) { return -60;})
              .attr("y", function(d) { return -60;})
              .attr("height", 400)
              .attr("width", 400);

          })
          // set back
          .on( 'mouseleave', function() {
            d3.select( this )
              .transition()
              .attr("x", function(d) { return -25;})
              .attr("y", function(d) { return -25;})
              .attr("height", 50)
              .attr("width", 50);
          });

  // Append hero name on roll over next to the node as well
  nodeEnter.append("text")
      .attr("class", "nodetext")
      .attr("x", x_browser)
      .attr("y", y_browser +15)
      .attr("fill", tcBlack)
      .text(function(d) { return d.title; });


  // Exit any old nodes.
  node.exit().remove();


  // Re-select for update.
  path = vis.selectAll("path.link");
  node = vis.selectAll("g.node");

function tick() {


    path.attr("d", function(d) {

     var dx = d.target.x - d.source.x,
           dy = d.target.y - d.source.y,
           dr = Math.sqrt(dx * dx + dy * dy);
           return   "M" + d.source.x + ","
            + d.source.y
            + "A" + dr + ","
            + dr + " 0 0,1 "
            + d.target.x + ","
            + d.target.y;
  });
    node.attr("transform", nodeTransform);
  }
}


/**
 * Gives the coordinates of the border for keeping the nodes inside a frame
 * http://bl.ocks.org/mbostock/1129492
 */
function nodeTransform(d) {
  d.x =  Math.max(maxNodeSize, Math.min(w - (d.imgwidth/2 || 16), d.x));
    d.y =  Math.max(maxNodeSize, Math.min(h - (d.imgheight/2 || 16), d.y));
    return "translate(" + d.x + "," + d.y + ")";
   }

/**
 * Toggle children on click.
 */
function click(d) {
  if (d.children) {
    d._children = d.children;
    d.children = null;
  } else {
    d.children = d._children;
    d._children = null;
  }

  update();
}


/**
 * Returns a list of all nodes under the root.
 */
function flatten(root) {
  var nodes = [];
  var i = 0;

  function recurse(node) {
    if (node.children)
      node.children.forEach(recurse);
    if (!node.id)
      node.id = ++i;
    nodes.push(node);
  }

  recurse(root);
  return nodes;
}


</script>

</body>
</html>